﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 版权所有 (c) 2022   保留所有权利。
 * CLR版本：4.0.30319.42000
 * 机器名称：DESKTOP-UL84BU5
 * 公司名称：
 * 命名空间：KingerRobot.WanliWMS.SpiService.Services.Curing
 * 唯一标识：499d74c8-f6f0-4af5-b911-c803c1f0f663
 * 文件名：BCuringManageImpl
 * 当前用户域：DESKTOP-UL84BU5
 * 
 * 创建者：zzl
 * 电子邮箱：1003590782@qq.com
 * 创建时间：2022/7/7 10:26:02
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using K8.CBB;
using KingerRobot.MexicoSailunMDC.Dao;
using KingerRobot.MexicoSailunWMS.Spi;
using KingerRobot.MexicoSailunWMS.SpiService.Services;
using Microsoft.EntityFrameworkCore.Internal;
//using MyBatis.DataMapper.Model.Sql;
using K8.EF;
using Microsoft.IdentityModel.Tokens;
using KingerRobot.MexicoSailunMES.Spi;
using KingerRobot.MexicoSailunMES.Spi.DTO;

namespace KingerRobot.MexicoSailunWMS.SpiService;

public class BCuringManageImpl : ICuringManageService
{

    private readonly static IRcsEquipCuringDitch _RcsEquipCuringDitch = new BRcsEquipCuringDitch();
    private readonly static IRcsEquipCuring _RcsEquipCuring = new BRcsEquipCuring();
    private readonly static IWmsOutOrderSummary _WmsOutOrderSummary = new BWmsOutOrderSummary();
    private readonly static IWmsOutOrderMaster _WmsOutOrderMaster = new BWmsOutOrderMaster();
    private readonly static ITask _Task = new BTask();
    private readonly static ITaskCmd _TaskCmd = new BTaskCmd();
    private readonly static IRcsEquip _RcsEquip = new BRcsEquip();
    private readonly static IProdMaterial _ProdMaterial = new BProdMaterial();
    private readonly static IWcsEquipLoc _WcsEquipLoc = new BWcsEquipLoc();
    private readonly static IWcsLocSku _WcsLocSku = new BWcsLocSku();
    private readonly static IRcsLocation _RcsLocation = new BRcsLocation();
    private readonly static IWcsNetInCuring _WcsNetInCuring = new BWcsNetInCuring();
    private readonly static IProdProduct _ProdProduct = new BProdProduct();
    private readonly static IWmsOutOrderSummarySafe _WmsOutOrderSummarySafe = new BWmsOutOrderSummarySafe();
    private readonly static IWmsPriorityCuring _WmsPriorityCuring = new BWmsPriorityCuring();
    private readonly static IWcsManualCuringRecord _WcsManualCuringRecord = new BWcsManualCuringRecord();

    #region 出库日志/出库异常日志
    public List<RequestTimeBean> GetRequestTime(RequestTimePara requestTimePara)
    {
        var list1 = Task.Run(() => GetNormalRequestTime(requestTimePara));//获取任务正常的出库日志
        var list2 = Task.Run(() => GetEmsExceptionRequestTime(requestTimePara));//获取EMS处创建的异常的出库日志
        var list = list1.Result.Union(list2.Result).OrderByDescending(f => f.CallTime).ToList();
        //var list3 = Task.Run(() => GetAngleExceptionRequestTime(requestTimePara));//获取角度扫描处创建的异常的出库日志
        //var list = list1.Result.Union(list2.Result).Union(list3.Result).OrderByDescending(f => f.CallTime).ToList();

        foreach (var item in list)
        {
            DateTime a, b;
            DateTime.TryParse(item.CrnStartTime, out a);
            DateTime.TryParse(item.CrnEndTime, out b);
            item.CrnTime = b.Subtract(a).TotalSeconds.ToInt();

            DateTime.TryParse(item.EmsStartTime, out a);
            DateTime.TryParse(item.EmsEndTime, out b);
            item.EmsTime = b.Subtract(a).TotalSeconds.ToInt();
        }

        return list;
    }

    public List<RequestTimeBean> GetExceptionRequestTime(RequestTimePara requestTimePara)
    {
        if (requestTimePara.ExceptionType == "EMS异常")
        {
            return GetEmsExceptionRequestTime(requestTimePara);//返回EMS处创建的异常的出库日志
        }
        else if (requestTimePara.ExceptionType == "角度扫描异常")
        {
            return GetAngleExceptionRequestTime(requestTimePara);//返回角度扫描处创建的异常的出库日志
        }
        else
        {
            var list1 = Task.Run(() => GetEmsExceptionRequestTime(requestTimePara));//获取EMS处创建的异常的出库日志
            var list2 = Task.Run(() => GetAngleExceptionRequestTime(requestTimePara));//获取角度扫描处创建的异常的出库日志
            var list = list1.Result.Union(list2.Result).OrderByDescending(f => f.CallTime).ToList();
            return list;
        }

    }

    public List<RequestTimeBean> GetNormalRequestTime(RequestTimePara requestTimePara)
    {
        if (requestTimePara is null || requestTimePara.BeginDate is null || requestTimePara.EndDate is null)
        {
            return null;
        }

        var startDate = requestTimePara.BeginDate.GetValueOrDefault();
        var endDate = requestTimePara.EndDate.GetValueOrDefault();

        //计算分页
        int stratCount = (requestTimePara.PageIndex - 1) * 10 + 1;
        int endCount = stratCount + requestTimePara.PageSize;

        List<RequestTimeBean> result = new List<RequestTimeBean>();
        var db = Db.Default;

        //1 获取loc信息
        var locs = db.RcsLocations.Where(T => T.UseFlag == 1).ToList();

        //2 获取硫化机列表
        var curings = db.RcsEquipCurings.Where(T => T.UseFlag == 1).ToList();

        var summarysQuery = from summarys in db.BakWmsOutOrderSummarys
                            join materials in db.ProdMaterials on summarys.MaterialId equals materials.Id
                            join wcstask in db.BakWcsTasks on summarys.Id equals wcstask.SummaryId
                            join skuproduct in db.ProdSkuProducts on wcstask.SkuId equals skuproduct.SkuId
                            join products in db.ProdProducts on skuproduct.ProductId equals products.Id
                            join rcsequip in db.RcsEquipCurings on wcstask.TargetEquip equals rcsequip.Id
                            join taskcmd2 in db.BakWcsTaskCmds on wcstask.Id equals taskcmd2.TaskId into grouping
                            from taskcmd2 in grouping.DefaultIfEmpty()
                            join taskcmd5 in db.BakWcsTaskCmds on wcstask.Id equals taskcmd5.TaskId into grouping2
                            from taskcmd5 in grouping2.DefaultIfEmpty()
                            where taskcmd2.TaskType == 2 && taskcmd5.TaskType == 5 && (summarys.FinishMode == 1 || summarys.FinishMode == 2 || summarys.FinishMode == 3)
                                  && summarys.CreateTime >= startDate && summarys.CreateTime >= endDate
                            select new { summarys, materials, wcstask, skuproduct, products, rcsequip, taskcmd2, taskcmd5 };

        if (!string.IsNullOrEmpty(requestTimePara.ProductCode))
        {
            summarysQuery = summarysQuery.Where(T => T.products.ProductCode == requestTimePara.ProductCode);
        }


        if (!string.IsNullOrEmpty(requestTimePara.CuringCode))
        {
            summarysQuery = summarysQuery.Where(T => T.rcsequip.CuringCode == requestTimePara.CuringCode);
        }

        var resultData = summarysQuery.ToList();
        foreach (var item in resultData)
        {
            RequestTimeBean requestTimeBean = new RequestTimeBean();
            requestTimeBean.Stock = item.summarys.Stock + "";
            var str = locs.Where(T => T.Id == item.summarys.TargetLoc).FirstOrDefault();
            requestTimeBean.CuringCode = str == null ? "" : str.LocCode;
            requestTimeBean.CuringName = str == null ? "" : str.LocName;
            requestTimeBean.ProductCode = item.products.ProductCode;
            requestTimeBean.Spec = item.materials.Spec;
            requestTimeBean.UpTime = item.summarys.CreateTime + "";
            requestTimeBean.FinishTime = item.taskcmd5.FinishTime + "";
            requestTimeBean.CallTime = item.summarys.CreateTime + "";
            requestTimeBean.TaskTime = item.wcstask.CreateTime + "";
            requestTimeBean.CrnStartTime = item.taskcmd2.UpdateTime + "";
            requestTimeBean.CrnEndTime = item.taskcmd2.FinishTime + "";
            requestTimeBean.ScannerTime = "";
            requestTimeBean.ScannerTaskTime = "";
            requestTimeBean.EmsStartTime = item.wcstask.UpdateTime + "";
            requestTimeBean.EmsEndTime = item.wcstask.FinishTime + "";
            requestTimeBean.Message = item.wcstask.RemarkMemo + "";
            result.Add(requestTimeBean);
        }

        return result;
    }

    public List<RequestTimeBean> GetEmsExceptionRequestTime(RequestTimePara requestTimePara)
    {
        if (requestTimePara is null || requestTimePara.BeginDate is null || requestTimePara.EndDate is null)
        {
            return new();
        }

        string startDate = ((DateTime)requestTimePara.BeginDate).ToString("yyyy-MM-dd");
        string endDate = ((DateTime)requestTimePara.EndDate).ToString("yyyy-MM-dd");

        var dbHelper = new DbHelper();
        var sql = new StringBuilder();
        sql.Append(@$"select CuringCode,CuringName,indexs,signs,ProductCode,Spec,MAX(UpTime) UpTime,Max(FinishTime) FinishTime,CallTime,TaskTime,CrnStartTime,CrnEndTime ,EmsStartTime ,EmsEndTime ,Message,Stock
                 from (
                        select wos.stock Stock,
                        pp.product_code ProductCode,
                        rl2.loc_code CuringCode,
                        rl2.loc_name CuringName,
                        rec.curing_mode_index indexs,
                        rec.curing_sign  signs,
                        pm.spec Spec,
                        bws.create_time UpTime,
                        bws.finish_time FinishTime,
                        wos.create_time CallTime,
                        bwt.create_time TaskTime,
                        bwtc.update_time CrnStartTime,
                        bwtc.finish_time CrnEndTime,
                        bwtc4.update_time EmsStartTime,
                        bwtc4.finish_time EmsEndTime,
                        wt.remark_memo Message
                        from
                        bak_wcs_task wt inner join rcs_location rl  on wt.start_loc = rl.objid AND  wt.start_loc in (select objid from rcs_location where loc_type = 9) AND wt.task_type = 9
                        LEFT JOIN  bak_wcs_task bwt on wt.sku_id = bwt.sku_id AND bwt.task_type = 2  
                        LEFT join bak_wms_out_order_summary wos on wos.objid = wt.summary_id
                        LEFT join rcs_equip_curing rec  on wos.target_loc = rec.loc_id 
                        left join prod_material pm on wos.material_id = pm.objid
                        left join rcs_location rl2 on wos.target_loc = rl2.objid 
                        --AND wt.target_loc = 20000102
                        left join bak_wcs_task_cmd 	bwtc on (bwtc.cmd_type = 2 OR  bwtc.cmd_type = 9) and bwtc.task_id = bwt.objid 
                        --left join bak_wcs_task_cmd bwtc2 on bwtc2.cmd_type = 3 and bwtc2.start_loc in (SELECT objid from rcs_location rl3 where rl3.loc_type=6) and bwtc2.task_id = bwt.objid -- 堆垛机输送
                        --left join bak_wcs_task_cmd bwtc3 on  (bwtc3.task_id = bwt.objid) AND ( (bwtc3.cmd_type = 3 and bwtc3.    start_loc in (SELECT objid from rcs_location rl4 where rl4.loc_type=8)) OR (bwtc3.cmd_type = 9 and bwtc3.target_loc in (SELECT objid  FROM rcs_location rl WHERE rl.loc_type = 9)))  -- 角度扫描输送
                        left join bak_wcs_task_cmd bwtc4 on  (bwtc4.cmd_type = 5 OR bwtc4.cmd_type = 9) and bwtc4.task_id  = wt.objid 
                        left join prod_sku_product psp on wt.sku_id = psp.sku_id 
                        left join prod_product pp on psp.product_id  = pp.objid 
                        left join (select * from bak_wms_out_order_summary bwoos) as bws
                        on bws.create_time < wos.create_time AND bws.target_loc = wos.target_loc
                        where wos.finish_mode = 1 AND
                        Convert(varchar(100),wos.create_time,23) >= '{startDate}' and
                        Convert(varchar(100),wos.create_time,23) <= '{endDate}' 
                        and wos.finish_mode = 1 and (wt.finish_mode = 1 or wt.finish_mode = 2 or wt.finish_mode = 3) and wt.use_flag = 1
                        ) tab 
                        where 1=1 and TaskTime is not null ");

        if (!string.IsNullOrWhiteSpace(requestTimePara.CuringCode))
        {
            sql.Append($"and CuringCode like '%{requestTimePara.CuringCode}%'");
        }
        if (!string.IsNullOrWhiteSpace(requestTimePara.CuringName))
        {
            sql.Append($"and CuringCode like '%{requestTimePara.CuringName}%'");
        }

        if (!string.IsNullOrWhiteSpace(requestTimePara.ProductCode))
        {
            sql.Append($"and ProductCode like '%{requestTimePara.ProductCode}%'");
        }
        sql.Append(@"GROUP by Stock,ProductCode,CuringCode,CuringName,Spec,CallTime,TaskTime,CrnStartTime,CrnEndTime ,EmsStartTime ,EmsEndTime ,Message ,indexs,signs
                        order by CallTime desc, CuringCode");

        dbHelper.CommandText = sql.ToString();
        dbHelper.CommandType = System.Data.CommandType.Text;
        var r = dbHelper.GetXDataTable();
        if (r == null || r.DataTable == null || r.DataTable.Rows == null || r.DataTable.Rows.Count == 0)
        {
            return new();
        }
        var db = Db.Default;
        var equipList = db.RcsEquips.ToList();
        List<RequestTimeBean> list = new List<RequestTimeBean>();
        for (int i = 0; i < r.DataTable.Rows.Count; i++)
        {

            var row = r.DataTable.Rows[i];
            if (row is not null)
            {
                var entity = r.DataTable.Rows[i].Map<RequestTimeBean>();
                entity.ExceptionType = "EMS异常";
                list.Add(entity);
            }
        }
        return list;
    }

    public List<RequestTimeBean> GetAngleExceptionRequestTime(RequestTimePara requestTimePara)
    {
        if (requestTimePara is null || requestTimePara.BeginDate is null || requestTimePara.EndDate is null)
        {
            return new();
        }

        string startDate = ((DateTime)requestTimePara.BeginDate).ToString("yyyy-MM-dd");
        string endDate = ((DateTime)requestTimePara.EndDate).ToString("yyyy-MM-dd");

        var dbHelper = new DbHelper();
        var sql = new StringBuilder();
        sql.Append(@$"select CuringCode,CuringName,indexs,signs,ProductCode,Spec,MAX(UpTime) UpTime,Max(FinishTime) FinishTime,CallTime,TaskTime,CrnStartTime,CrnEndTime ,EmsStartTime ,EmsEndTime ,Message,Stock
                 from (
                        select wos.stock Stock,
                        pp.product_code ProductCode,
                        rl2.loc_code CuringCode,
                        rl2.loc_name CuringName,
                        rec.curing_mode_index indexs,
                        rec.curing_sign  signs,
                        pm.spec Spec,
                        bws.create_time UpTime,
                        bws.finish_time FinishTime,
                        wos.create_time CallTime,
                        bwt.create_time TaskTime,
                        bwtc.update_time CrnStartTime,
                        bwtc.finish_time CrnEndTime,
                        --bwtc3.create_time ScannerTime,
                        --bwtc3.update_time ScannerTaskTime,
                        bwtc4.update_time EmsStartTime,
                        bwtc4.finish_time EmsEndTime,
                        bwt.remark_memo Message
                        from
                        bak_wcs_task wt inner join rcs_location rl  on wt.start_loc = rl.objid AND  wt.start_loc in (select objid from rcs_location where loc_type = 9) AND wt.task_type = 9
                        LEFT JOIN  bak_wcs_task bwt on wt.sku_id = bwt.sku_id AND bwt.task_type = 9 AND bwt.target_loc in (SELECT objid  FROM rcs_location rl WHERE rl.loc_type = 7)
                        LEFT join bak_wms_out_order_summary wos on wos.objid = wt.summary_id
                        LEFT join rcs_equip_curing rec  on wt.target_equip = rec.objid 
                        left join prod_material pm on wos.material_id = pm.objid
                        left join rcs_location rl2 on wos.target_loc = rl2.objid AND wt.target_loc = 20000102
                        left join bak_wcs_task_cmd 	bwtc on bwtc.cmd_type = 2  and bwtc.task_id = bwt.objid 
                        --left join bak_wcs_task_cmd bwtc2 on bwtc2.cmd_type = 3 and bwtc2.start_loc in (SELECT objid from rcs_location rl3 where rl3.loc_type=6) and bwtc2.task_id = bwt.objid -- 堆垛机输送
                        --left join bak_wcs_task_cmd bwtc3 on  (bwtc3.task_id = bwt.objid) AND ( (bwtc3.cmd_type = 3 and bwtc3.start_loc in (SELECT objid from rcs_location rl4 where rl4.loc_type=8)) OR (bwtc3.cmd_type = 9 and bwtc3.target_loc in (SELECT objid  FROM rcs_location rl WHERE rl.loc_type = 9)))  -- 角度扫描输送
                        left join bak_wcs_task_cmd bwtc4 on   bwtc4.cmd_type = 9  and bwtc4.task_id  = wt.objid 
                        left join prod_sku_product psp on wt.sku_id = psp.sku_id 
                        left join prod_product pp on psp.product_id  = pp.objid 
                        left join (select * from bak_wms_out_order_summary bwoos) as bws
                        on bws.create_time < wos.create_time AND bws.target_loc = wos.target_loc
                        where wos.finish_mode = 1 AND
                        Convert(varchar(100),wos.create_time,23) >= '{startDate}' and
                        Convert(varchar(100),wos.create_time,23) <= '{endDate}' 
                        and wos.finish_mode = 1 and (wt.finish_mode = 1 or wt.finish_mode = 2 or wt.finish_mode = 3) and wt.use_flag = 1
                        ) tab 
                        where 1=1  and TaskTime is not null  ");

        if (!string.IsNullOrWhiteSpace(requestTimePara.CuringCode))
        {
            sql.Append($"and CuringCode like '%{requestTimePara.CuringCode}%'");
        }
        if (!string.IsNullOrWhiteSpace(requestTimePara.CuringName))
        {
            sql.Append($"and CuringCode like '%{requestTimePara.CuringName}%'");
        }

        if (!string.IsNullOrWhiteSpace(requestTimePara.ProductCode))
        {
            sql.Append($"and ProductCode like '%{requestTimePara.ProductCode}%'");
        }
        sql.Append(@"GROUP by Stock,ProductCode,CuringCode,CuringName,Spec,CallTime,TaskTime,CrnStartTime,CrnEndTime,EmsStartTime ,EmsEndTime ,Message ,indexs,signs
                        order by CallTime desc, CuringCode");

        dbHelper.CommandText = sql.ToString();
        dbHelper.CommandType = System.Data.CommandType.Text;
        var r = dbHelper.GetXDataTable();
        if (r == null || r.DataTable == null || r.DataTable.Rows == null || r.DataTable.Rows.Count == 0)
        {
            return new();
        }
        var db = Db.Default;
        var equipList = db.RcsEquips.ToList();
        List<RequestTimeBean> list = new List<RequestTimeBean>();
        for (int i = 0; i < r.DataTable.Rows.Count; i++)
        {
            var entity = r.DataTable.Rows[i].Map<RequestTimeBean>();
            entity.ExceptionType = "角度扫描异常";
            list.Add(entity);
        }

        return list;
    }

    #endregion


    public List<CuringCallBean> GetCuringCallBeans(CuringCallPara curingCallPara)
    {
        var curings = _RcsEquipCuring.GetAllEquipCurings(); // 硫化机
        var curingDitches = _RcsEquipCuringDitch.GetRcsEquipCuringDitches(); // 硫化排

        var curingIds = curings.Select(t => t.Id).ToList();
        var curingLocs = _WcsEquipLoc.GetEquipLocListByIds(curingIds); // 硫化机-位置
        var equips = _RcsEquip.GetRcsEquipByIds(curingIds);

        var summaries = _WmsOutOrderSummary.GetOrderSummaryList(); // 出库订单
        var tasks = _Task.GetTaskByType((int)EnumTaskType.Exwarehouse); // 出库任务
        var skuIds = tasks.Select(t => t.SkuId).ToList();
        var locSkus = _WcsLocSku.GetWcsLocSkuBySkuIds(skuIds); // 胎胚位置
        var locIds = locSkus.Select(t => t.LocId).ToList();
        var locations = _RcsLocation.GetLocationsByLocIds(locIds); // 位置

        var materialIds = summaries.Select(t => t.MaterialId).ToList();
        var materials = _ProdMaterial.GetMaterialListByIds(materialIds); // 物料

        var masterIds = summaries.Select(t => t.MasterId).ToList();
        var masters = _WmsOutOrderMaster.GetOutOrderMasterByIds(masterIds); // 出库订单-主表

        var summariesInfos = summaries.Join(materials, f => f.MaterialId, s => s.Id, (f, s) => new
        {
            Summaries = f,
            Materials = s,
        }).Join(masters, f => f.Summaries.MasterId, s => s.Id, (f, s) => new
        {
            f.Summaries,
            f.Materials,
            Master = s,
        }).GroupJoin(tasks, f => f.Summaries.Id, s => s.SummaryId, (f, s) => new
        {
            f.Summaries,
            f.Materials,
            f.Master,
            Tasks = s,
        }).SelectMany(t => t.Tasks.DefaultIfEmpty(), (f, s) => new
        {
            f.Summaries,
            f.Materials,
            f.Master,
            Tasks = s,
        }).GroupJoin(locSkus, f => f.Tasks?.SkuId, s => s.SkuId, (f, s) => new
        {
            f.Summaries,
            f.Materials,
            f.Master,
            f.Tasks,
            Locs = s,
        }).SelectMany(t => t.Locs.DefaultIfEmpty(), (f, s) => new
        {
            f.Summaries,
            f.Materials,
            f.Master,
            f.Tasks,
            Locs = s,
        }).GroupJoin(locations, f => f.Locs?.LocId, s => s.Id, (f, s) => new
        {
            f.Summaries,
            f.Materials,
            f.Master,
            f.Tasks,
            f.Locs,
            LocName = s,
        }).SelectMany(t => t.LocName.DefaultIfEmpty(), (f, s) => new
        {
            f.Summaries,
            f.Materials,
            f.Master,
            f.Tasks,
            f.Locs,
            LocName = s,
        }).ToList();


        var result = curings.Join(curingDitches, f => f.DitchId, s => s.Id, (f, s) => new
        {
            Curing = f,
            Ditch = s,
        }).Join(curingLocs, f => f.Curing.Id, s => s.EquipId, (f, s) => new
        {
            f.Curing,
            f.Ditch,
            TargetLoc = s.LocId,
        })
        .Join(equips, f => f.Curing.Id, s => s.Id, (f, s) => new
        {
            f.Curing,
            f.Ditch,
            f.TargetLoc,
            Equips = s
        }).GroupJoin(summariesInfos, f => f.TargetLoc, s => s.Summaries.TargetLoc, (f, s) => new
        {
            f.Curing,
            f.Ditch,
            f.TargetLoc,
            f.Equips,
            Summaries = s,
        }).SelectMany(t => t.Summaries.DefaultIfEmpty(), (f, s) => new
        {
            f.Curing,
            f.Ditch,
            f.TargetLoc,
            f.Equips,
            Summaries = s?.Summaries,
            Materials = s?.Materials,
            Tasks = s?.Tasks,
            Master = s?.Master,
            Locs = s?.Locs,
            LocName = s?.LocName,
        }).ToList();

        if (curingCallPara is not null && curingCallPara.DitchId is not null && curingCallPara?.DitchId != 0)
        {
            result = result.Where(t => t.Curing.DitchId == curingCallPara.DitchId).ToList();
        }

        if (!string.IsNullOrWhiteSpace(curingCallPara?.CuringCode))
        {
            result = result.Where(t => t.Curing.CuringCode.Contains(curingCallPara.CuringCode)).ToList();
        }
        if (!string.IsNullOrWhiteSpace(curingCallPara?.CuringName))
        {
            result = result.Where(t => t.Equips.EquipName.Contains(curingCallPara.CuringName)).ToList();
        }

        if (!string.IsNullOrWhiteSpace(curingCallPara?.Spec))
        {
            result = result.Where(t => t.Materials is not null ? t.Materials.Spec.Contains(curingCallPara.Spec) : false).ToList();
        }
        if (!string.IsNullOrWhiteSpace(curingCallPara?.MaterialCode))
        {
            result = result.Where(t => t.Materials is not null ? t.Materials.MaterialCode.Contains(curingCallPara.MaterialCode) : false).ToList();
        }

        return result.Select(t => new CuringCallBean
        {
            CuringCode = t.Curing.CuringCode,
            CuringName = t.Equips.EquipName,
            CuringMode = _RcsEquipCuring.GetCuringRL(t.Curing.Id.GetValueOrDefault())?.Mode,
            DitchName = t.Ditch.EquipName,
            CallCuring = t.Summaries is not null ? "是" : "否",
            Spec = t.Materials?.Spec,
            MaterialCode = t.Materials?.MaterialCode,
            TaskNo = t.Tasks?.TaskNo,
            OrderCode = t.Master?.OrderCode,
            LocName = t.LocName?.LocName,
            SummaryId = t.Summaries?.Id,
            TargetLoc = t.TargetLoc
        }).OrderBy(t => t.CuringCode).ToList();
    }

    [OperationLog("硫化要胎置位")]
    public string CuringComplete(long locId, long userId, string userName, string clientHost)
    {
        var summary = _WmsOutOrderSummary.GetOutOrderSummaryByLocId(locId);
        if (summary != null)
        {
            var master = _WmsOutOrderMaster.GetOutOrderMasterById(summary.MasterId.GetValueOrDefault());
            if (master.OrderType == (int)EnumCodeOutOrderType.WarehouseLocation)
            {
                return "当前订单不是硫化请料/条码请料/规格请料，不允许异常完成";
            }
            if (!string.IsNullOrWhiteSpace(summary.Serno))
            {
                return "当前订单不是硫化请料订单，不允许异常完成";
            }
            var task = _Task.GetTasksBySummaryId(summary.Id.GetValueOrDefault());
            if (task?.TaskType == (int)EnumTaskType.EMS)
            {
                return "当前订单已生成EMS任务，不允许异常完成";
            }

            if (task != null)
            {
                var result = _WmsOutOrderSummary.BakAndDeleteOutOrderSummary(summary.Id.GetValueOrDefault());
                result += _WmsOutOrderSummarySafe.AddOutOrderSumarySafe(summary.Id.GetValueOrDefault(), summary.TargetLoc.GetValueOrDefault(), 0);
                var count = _WmsOutOrderSummary.GetOrderSummaryList().Where(t => t.MasterId == master.Id).Count();
                if (count == 0)
                {
                    _WmsOutOrderMaster.BakAndDeleteOutOrderMaster(master);
                }
                _Task.UpdateTaskCallDelete(task.Id.GetValueOrDefault(), 1);
            }
            else
            {
                var result = _WmsOutOrderSummary.BakAndDeleteOutOrderSummary(summary.Id.GetValueOrDefault());
                result = _WmsOutOrderSummarySafe.AddOutOrderSumarySafe(summary.Id.GetValueOrDefault(), summary.TargetLoc.GetValueOrDefault(), 0);


                var count = _WmsOutOrderSummary.GetOrderSummaryList().Where(t => t.MasterId == master.Id).Count();
                if (count == 0)
                {
                    _WmsOutOrderMaster.BakAndDeleteOutOrderMaster(master);
                }

            }

        }
        else
        {
            var result = _WmsOutOrderSummarySafe.AddOutOrderSumarySafe(0, locId, 0);
            if (result > 0)
            {
                return "成功";
            }
            else
            {
                return "失败";
            }
        }
        return "成功";
    }
    public List<CuringDitch> GetCuringDitches()
    {
        var curingDitches = _RcsEquipCuringDitch.GetRcsEquipCuringDitches();
        return curingDitches.Select(t => new CuringDitch
        {
            Id = t.Id.GetValueOrDefault(),
            DitchName = t.EquipName,
        }).OrderByDescending(t => t.Id).ToList();
    }

    public List<string> GetCuringCodes()
    {
        var result = _RcsEquipCuring.GetCuringCodes();
        return result;
    }

    public List<CuringEquipBean> GetCuringEquipBeans(CuringEquipPara curingEquipPara)
    {
        var curings = _RcsEquipCuring.GetAllEquipCurings(); // 硫化机
        var curingDitches = _RcsEquipCuringDitch.GetRcsEquipCuringDitches(); // 硫化排
        var curingIds = curings.Select(t => t.Id).ToList();
        var equipLocs = _WcsEquipLoc.GetEquipLocList();
        var curingLocs = equipLocs.Where(t => curingIds.Contains(t.EquipId)).ToList();  // _WcsEquipLoc.GetEquipLocListByIds(curingIds); // 硫化机-位置
        var rcsEquips = _RcsEquip.GetAllEquips();
        var equips = rcsEquips.Where(t => curingIds.Contains(t.Id)).ToList(); // _RcsEquip.GetRcsEquipByIds(curingIds);

        var summaries = _WmsOutOrderSummary.GetOrderSummaryList(); // 出库订单
        var tasks = _Task.GetTaskByType((int)EnumTaskType.Exwarehouse); // 出库任务

        var materialIds = summaries.Select(t => t.MaterialId).ToList();
        var materials = _ProdMaterial.GetMaterialListByIds(materialIds); // 物料

        var summariesInfos = summaries.Join(materials, f => f.MaterialId, s => s.Id, (f, s) => new
        {
            Summaries = f,
            Materials = s,
        }).GroupJoin(tasks, f => f.Summaries.Id, s => s.SummaryId, (f, s) => new
        {
            f.Summaries,
            f.Materials,
            Tasks = s,
        }).SelectMany(t => t.Tasks.DefaultIfEmpty(), (f, s) => new
        {
            f.Summaries,
            f.Materials,
            Tasks = s,
        }).ToList();


        var result = curings.Join(curingDitches, f => f.DitchId, s => s.Id, (f, s) => new
        {
            Curing = f,
            Ditch = s,
        }).Join(curingLocs, f => f.Curing.Id, s => s.EquipId, (f, s) => new
        {
            f.Curing,
            f.Ditch,
            TargetLoc = s.LocId,
        })
        .Join(equips, f => f.Curing.Id, s => s.Id, (f, s) => new
        {
            f.Curing,
            f.Ditch,
            f.TargetLoc,
            Equips = s
        }).GroupJoin(summariesInfos, f => f.TargetLoc, s => s.Summaries.TargetLoc, (f, s) => new
        {
            f.Curing,
            f.Ditch,
            f.TargetLoc,
            f.Equips,
            Summaries = s,
        }).SelectMany(t => t.Summaries.DefaultIfEmpty(), (f, s) => new
        {
            f.Curing,
            f.Ditch,
            f.TargetLoc,
            f.Equips,
            Summaries = s?.Summaries,
            Materials = s?.Materials,
            Tasks = s?.Tasks,
        }).OrderBy(t => t.Ditch.EquipName).ToList();

        if (curingEquipPara is not null && curingEquipPara.DitchId != 0 && curingEquipPara.DitchId is not null)
        {
            result = result.Where(t => t.Curing.DitchId == curingEquipPara.DitchId).ToList();
        }

        if (!string.IsNullOrWhiteSpace(curingEquipPara?.CuringCode))
        {
            result = result.Where(t => t.Curing.CuringCode.Contains(curingEquipPara.CuringCode.Trim())).ToList();
        }
        if (!string.IsNullOrWhiteSpace(curingEquipPara?.CuringName))
        {
            result = result.Where(t => t.Equips.EquipName.Contains(curingEquipPara.CuringName.Trim())).ToList();
        }

        if (!string.IsNullOrWhiteSpace(curingEquipPara?.Spec))
        {
            result = result.Where(t => t.Materials is not null ? t.Materials.Spec.Contains(curingEquipPara.Spec) : false).ToList();
        }
        if (!string.IsNullOrWhiteSpace(curingEquipPara?.MaterialCode))
        {
            result = result.Where(t => t.Materials is not null ? t.Materials.MaterialCode.Contains(curingEquipPara.MaterialCode) : false).ToList();
        }
        if (!string.IsNullOrWhiteSpace(curingEquipPara?.EquipEnable) && Convert.ToInt32(curingEquipPara?.EquipEnable.Trim()) >= 0) //硫化机是否可用
        {
            result = result.Where(t => t.Equips.EquipEnable == Convert.ToInt32(curingEquipPara?.EquipEnable.Trim())).ToList();
        }

        return result.Select(t => new CuringEquipBean
        {
            CuringCode = t.Curing.CuringCode,
            CuringName = t.Equips.EquipName,
            CuringMode = _RcsEquipCuring.GetCuringRL(t.Curing.Id.GetValueOrDefault())?.Mode,
            DitchName = t.Ditch.EquipName,
            CallCuring = t.Summaries is not null ? "是" : "否",
            Spec = t.Materials?.Spec,
            MaterialCode = t.Materials?.MaterialCode,
            Suspend = t.Curing.CuringStatus == 1 ? "暂停" : "未暂停",
            Stop = t.Curing.CuringStatus == 2 ? "停止" : "未停止",
            Transport = t.Tasks?.TaskStatus == (int)EnumTaskStatus.Executed ? "已输送" : "未输送",
            CuringEmpty = t.Summaries is not null ? "不可放胎" : "可放胎",
            EquipEnable = t.Equips.EquipEnable == 1 ? "可用" : "禁用"
        }).OrderBy(t => t.CuringCode).ToList();

    }

    public List<CuringLocBean> GetCuringLocBeans()
    {
        var netInCurings = _WcsNetInCuring.GetWcsNetinCurings();
        var locs = netInCurings.Select(t => t.TranLoc).ToList();

        var locations = _RcsLocation.GetLocationsByLocIds(locs); // 硫化取货位
        var locSkus = _WcsLocSku.GetWcsLocSkuByLocIds(locs); // 是否有货

        var skuIds = locSkus.Select(t => t.SkuId).ToList();
        var tasks = _Task.GetTaskBySkuIds(skuIds); // 任务

        var targetLocs = tasks.Select(t => t.TargetLoc).ToList();
        var targets = _RcsLocation.GetLocationsByLocIds(targetLocs); // 目标货位

        var summaries = _WmsOutOrderSummary.GetOrderSummaryList(); // 出库订单

        var materialIds = summaries.Select(t => t.MaterialId).ToList();
        var materials = _ProdMaterial.GetMaterialListByIds(materialIds); // 物料

        List<CuringLocBean> curingLocBeans = new List<CuringLocBean>();
        netInCurings.ForEach(item =>
        {

            var locName = locations.Where(t => t.Id == item.TranLoc).FirstOrDefault()?.LocName;
            var locSku = locSkus.Where(t => t.LocId == item.TranLoc).FirstOrDefault();
            var locTime = locSku?.CreateTime;
            var skuId = locSku?.SkuId;
            var hasLoc = locTime is null ? "无" : "有";
            var task = tasks.Where(t => t.SkuId == skuId).FirstOrDefault();
            var targetLoc = task?.TargetLoc;
            var targetEquip = task?.TargetEquip;

            var curingName = targets.Where(t => t.Id == targetLoc).FirstOrDefault()?.LocName;
            var curingMode = _RcsEquipCuring.GetCuringRL(targetEquip.GetValueOrDefault())?.Mode;

            var materialId = summaries.Where(t => t.TargetLoc == targetLoc).FirstOrDefault()?.MaterialId;
            var material = materials.Where(t => t.Id == materialId).FirstOrDefault();
            var spec = material?.Spec;
            var materialCode = material?.MaterialCode;

            CuringLocBean curingLocBean = new()
            {
                LocName = locName,
                LocTime = locTime,
                HasLoc = hasLoc,
                Spec = spec,
                MaterialCode = materialCode,
                CuringName = curingName,
                CuringMode = curingMode,
            };
            curingLocBeans.Add(curingLocBean);
        });
        return curingLocBeans;
    }


    public List<CuringDitchBean> CuringDitchBeans()
    {
        // 硫化排
        var curingDitches = _RcsEquipCuringDitch.GetRcsEquipCuringDitches();
        // 任务目标汇总
        var taskGroups = _Task.GetTargetLocTaskGroup();
        // 硫化机
        var equipCurings = _RcsEquipCuring.GetAllEquipCuringLoc();


        var ditchBeans = curingDitches.Select(t => new CuringDitchBean
        {
            Id = t.Id.GetValueOrDefault(),
            DitchName = t.EquipName,
            MaxCount = t.MaxCount,
            Suspend = t.EquipStatus == 1 ? true : false,
            Stop = t.EquipStatus == 2 ? true : false,
            Reason = t.Reason

        }).ToList();

        ditchBeans.ForEach(item =>
        {
            var curingIds = equipCurings.Where(t => t.PORcsEquipCuring.DitchId == item.Id).Select(t => t.POWcsEquipLoc.LocId).ToList();
            var taskCount = taskGroups.Where(t => curingIds.Contains(t.LocId)).Sum(t => t.Count);
            item.RealCount = taskCount;
        });

        return ditchBeans;
    }

    public int UpdateDitchSuspend(long id)
    {
        var result = _RcsEquipCuringDitch.UpdateDitchSuspend(id);
        return result;
    }

    public int UpdateDitchStop(long id)
    {
        var result = _RcsEquipCuringDitch.UpdateDitchStop(id);
        return result;
    }


    public CuringBean GetCuringMode(int taskNo)
    {

        var db = Db.Default;
        var task = _Task.GetTaskByTaskNo(taskNo);
        if (task is null)
        {
            return null;
        }

        var taskCmd = _TaskCmd.GetTaskCmdByTaskNo(taskNo);

        var equipId = _WcsEquipLoc.GetEquipIdByLocId(task.TargetLoc.GetValueOrDefault());

        // 获取设备是：左模、右模
        var curingRL = _RcsEquipCuring.GetCuringRL(equipId);

        var skuId = task.SkuId.GetValueOrDefault();

        var barCode = _ProdProduct.GetCodeBySkuId(skuId);

        var summary = _WmsOutOrderSummary.GetOutOrderSummaryByLocId(task.TargetLoc.GetValueOrDefault());

        return new()
        {
            CuringCode = curingRL?.CuringCode,
            Mode = curingRL?.Mode,
            BarCode = barCode,
            Spray = taskCmd?.IsSpray > 0,
            Serno = summary.Serno,
        };

    }

    public int AddCuringMesBean(CuringBean curingBean)
    {
        if (curingBean is null)
        {
            return 0;
        }

        // TODO (注释)RpcHelper， 迁移到 BRpc 中实现
        //var middleMesService = K8.RSF.Client.Create<IMiddleMesService>();

        //middleMesService.AddOutWarehouseFinish(new()
        //{
        //    BarCode = curingBean.BarCode,
        //    CuringCode = curingBean.CuringCode,
        //    Mode = curingBean.Mode,
        //    CreateTime = DateTime.Now,
        //    Serno = curingBean.Serno,
        //});


        return 1;
    }

    [OperationLog("硫化排限制数量修改")]
    public int UpdateCuringDitchCount(UpdateCuringParam updateCuringParam, long userId, string userName, string clientHost)
    {
        if (updateCuringParam is null)
        {
            return -1;
        }
        if (updateCuringParam.count < 0)
        {
            return -2;
        }
        var id = updateCuringParam.id;
        var count = updateCuringParam.count;
        var reason = updateCuringParam.Remark;

        var result = _RcsEquipCuringDitch.UpdateDicthCount(id, count, reason);
        return result;
    }

    public string GetCuringCallMaterial()
    {
        var db = Db.Default;
        var state = db.WmsSettings.Where(t => t.Code == "Curing_Call_Material").FirstOrDefault();
        if (state == null) return "0";
        return state.Value;
    }
    public int SetCuringCallMaterial(string value)
    {
        var db = Db.Default;
        var result = 0;
        var setting = db.WmsSettings.Where(t => t.Code == "Curing_Call_Material").FirstOrDefault();
        if (setting is not null)
        {
            setting.Value = value;
            result = db.SaveChanges();
        }
        return result;
    }


    public List<CuringDetailsBean> GetCuringDetailsByDitch(long ditchId)
    {
        //拿到所有硫化机位
        var curingCodeList = _RcsEquipCuring.GetCuringCodesByDitchId(ditchId);

        List<CuringDetailsBean> curingDetailsList = new();

        //获取硫化位的请料单
        foreach (var curingCode in curingCodeList)
        {
            CuringDetailsBean curingDetails = new();
            //获取当前硫化机名
            var equipName = _RcsEquip.GetRcsEquipByCode(curingCode).EquipName.Split('机')[0] + $"机({curingCode})";
            curingDetails.CuringName = equipName;
            //获取硫化机左右膜
            var curingList = _RcsEquipCuring.GetCuringByCode(curingCode);

            //循环每个硫化位 获取订单
            foreach (var curing in curingList)
            {
                OutOrderSummaryKanBan kan = new();
                var summary = _WmsOutOrderSummary.GetOutOrderSummaryByLocId(curing.LocId ?? 0);

                if (summary is not null)
                {
                    kan = _WmsOutOrderSummary.GetOutOrderSummarySchedule(summary);
                }
                else
                {
                    var loc = _RcsLocation.GetLocationById(curing.LocId ?? 0);
                    kan.TargetLoc = loc.LocName;
                    string lOrR = loc.LocName.Split('机')[1].Substring(0, 1);
                    kan.LeftOrRight = Convert.ToInt32(lOrR);
                }
                curingDetails.outOrderSummaryKanBans.Add(kan);
            }
            curingDetailsList.Add(curingDetails);
        }
        return curingDetailsList;

    }

    public List<CuringTaskCountBean> GetCuringDitchesTask(DateTime BeginDate, DateTime EndDate)
    {
        var result = _RcsEquipCuringDitch.GetCuringDitchesTask(BeginDate, EndDate);
        return result;
    }


    public List<POWmsPriorityCuring> GetAllPriorityCurings(priorityCuringParam param)
    {
        var result = _WmsPriorityCuring.GetAllPriorityCurings();
        if (!string.IsNullOrWhiteSpace(param.CuringCode))
        {
            result = result.Where(t => t.CuringCode.Contains(param.CuringCode)).ToList();
        }
        return result;
    }
    public int DeletePriorityCuringById(long Id)
    {
        var result = 0;
        if (Id == 0)
        {
            return result;
        }
        result = _WmsPriorityCuring.DeletePriorityCuringById(Id);
        return result;
    }
    public int AddPriorityCuringById(priorityCuringParam param)
    {
        var result = 0;
        if (param is null)
        {
            return result;
        }
        result = _WmsPriorityCuring.AddPriorityCuringById(param);
        return result;
    }
    public int UpdatePriorityCuringById(priorityCuringParam param)
    {
        var result = 0;
        if (param is null)
        {
            return result;
        }
        result = _WmsPriorityCuring.UpdatePriorityCuringById(param);
        return result;
    }

    public List<POWcsManualCuringRecord> GetManualCuringRecord(manualCuringParam param)
    {

        var result = _WcsManualCuringRecord.GetManualCuringRecord(param.StartDate, param.EndDate);

        if (!String.IsNullOrEmpty(param?.LocName))
        {
            result = result.Where(t => t.LocName.Contains(param.LocName)).ToList();
        }
        if (!String.IsNullOrEmpty(param?.ProductCode))
        {
            result = result.Where(t => t.ProductCode.Contains(param.ProductCode)).ToList();
        }
        return result;
    }
    public List<TcmInfo> GetInCuringInfos(inCuringParam param)
    {
        var tcmNo = param.TcmNo;
        var mesServices = K8.RSF.Client.Create<IMesService>();
        var result = mesServices.GetWMSAllInCuringInfos();

        if (!String.IsNullOrWhiteSpace(tcmNo))
        {
            result = result.Where(t => t.TCM_NO.Contains(tcmNo)).ToList();
        }
        return result;
    }

}